package cn.iocoder.yudao.module.alipay.service.payrecord;

import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import cn.iocoder.yudao.module.alipay.controller.admin.payrecord.vo.*;
import cn.iocoder.yudao.module.alipay.dal.dataobject.payrecord.PayRecordDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import cn.iocoder.yudao.module.alipay.convert.payrecord.PayRecordConvert;
import cn.iocoder.yudao.module.alipay.dal.mysql.payrecord.PayRecordMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.alipay.enums.ErrorCodeConstants.*;

/**
 * 支付记录 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class PayRecordServiceImpl implements PayRecordService {

    @Resource
    private PayRecordMapper payRecordMapper;

    @Resource
    private AdminUserApi adminUserApi;

    @Override
    public Long createPayRecord(PayRecordCreateReqVO createReqVO) {
        // 插入
        PayRecordDO payRecord = PayRecordConvert.INSTANCE.convert(createReqVO);
        payRecordMapper.insert(payRecord);
        // 返回
        return payRecord.getId();
    }

    @Override
    public void updatePayRecord(PayRecordUpdateReqVO updateReqVO) {
        // 校验存在
        validatePayRecordExists(updateReqVO.getId());
        // 更新
        PayRecordDO updateObj = PayRecordConvert.INSTANCE.convert(updateReqVO);
        payRecordMapper.updateById(updateObj);
    }

    @Override
    public void deletePayRecord(Long id) {
        // 校验存在
        validatePayRecordExists(id);
        // 删除
        payRecordMapper.deleteById(id);
    }

    private void validatePayRecordExists(Long id) {
        if (payRecordMapper.selectById(id) == null) {
            throw exception(PAY_RECORD_NOT_EXISTS);
        }
    }

    @Override
    public PayRecordDO getPayRecord(Long id) {
        return payRecordMapper.selectById(id);
    }

    @Override
    public List<PayRecordDO> getPayRecordList(Collection<Long> ids) {
        return payRecordMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<PayRecordDO> getPayRecordPage(PayRecordPageReqVO pageReqVO) {
        return payRecordMapper.selectPage(pageReqVO);
    }

    @Override
    public List<PayRecordDO> getPayRecordList(PayRecordExportReqVO exportReqVO) {
        return payRecordMapper.selectList(exportReqVO);
    }

    @Override
    public Map<String, Object> getHomePageCollectData(PayRecordExportReqVO pageVO) {
        AdminUserRespDTO user = null;
        if(pageVO.getCreator()!=null){
             user = adminUserApi.getUser(Long.valueOf(pageVO.getCreator()));
        }
        //是否为芋道源码
        if("1".equals(pageVO.getCreator())){
            pageVO.setCreator(null);
        }
        LocalDateTime today = LocalDateTime.now();

        LocalDateTime yesterday = today.minusDays(1);
        DecimalFormat decimalFormat = new DecimalFormat("#.00");
        Map<String, Object> resultMap = new HashMap<>();
        LocalDateTime[] todayDateTime = new LocalDateTime[2];
        todayDateTime[0] = today.withHour(0).withMinute(0).withNano(0);
        todayDateTime[1] = today.withHour(23).withMinute(59).withNano(59);
        LambdaQueryWrapperX<PayRecordDO>  payRecordDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
        payRecordDOLambdaQueryWrapperX
                .eqIfPresent(PayRecordDO::getCreator, pageVO.getCreator())
                .betweenIfPresent(PayRecordDO::getPayTime, todayDateTime);
        Double todayRetailAmount = payRecordMapper.todaySumAmount(payRecordDOLambdaQueryWrapperX);
        Integer countToday = payRecordMapper.countTodayOrder(payRecordDOLambdaQueryWrapperX);

        //当日营业额
        if (todayRetailAmount == null) {
            todayRetailAmount=(0.00);
        }
        //今日付款订单
        if (countToday == null) {
            countToday= 0 ;
        }

        //营业额
        LocalDateTime[] yesterTodayDateTime = new LocalDateTime[2];
        yesterTodayDateTime[0] = yesterday.withHour(0).withMinute(0).withNano(0);
        yesterTodayDateTime[1] = yesterday.withHour(23).withMinute(59).withNano(59);

        payRecordDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
        payRecordDOLambdaQueryWrapperX
                .eqIfPresent(PayRecordDO::getCreator, pageVO.getCreator())
                    .betweenIfPresent(PayRecordDO::getPayTime, yesterTodayDateTime);
        Double yesterdayRetailAmount = payRecordMapper.todaySumAmount(payRecordDOLambdaQueryWrapperX);
        Integer countYesterday = payRecordMapper.countTodayOrder(payRecordDOLambdaQueryWrapperX);
        //当日营业额
        if (yesterdayRetailAmount == null) {
            yesterdayRetailAmount=(0.00);
        }
        //昨日付款订单
        if (countYesterday == null) {
            countYesterday= 0 ;
        }
        //今日营业额,、昨日营业额，日环比
        Map<String,Object> retailAmount = new HashMap<>();
        retailAmount.put("todayRetailAmount", todayRetailAmount);
        retailAmount.put("yesterdayRetailAmount", yesterdayRetailAmount);
        double gapRetailAmount = todayRetailAmount.doubleValue() - yesterdayRetailAmount.doubleValue();
        retailAmount.put("proportion","0%");
        if(gapRetailAmount!=0){
            retailAmount.put("proportion",gapRetailAmount*100+"%");
            if(yesterdayRetailAmount!=0){
                //日环比，今天减去昨天/昨天
                double proportion = gapRetailAmount / yesterdayRetailAmount.doubleValue()*100;
                retailAmount.put("proportion",decimalFormat.format(proportion)+"%");
            }
        }
        resultMap.put("retailAmount", retailAmount);

        //今日订单,、昨日订单，日环比
        Map<String,Object> countOrder = new HashMap<>();
        countOrder.put("countToday", countToday);
        countOrder.put("countYesterday", countYesterday);
        double gapCountOrder = countToday.doubleValue() - countYesterday.doubleValue();
        countOrder.put("proportion","0%");
        if(gapCountOrder!=0){
            countOrder.put("proportion",gapCountOrder*100+"%");
            if(countYesterday!=0){
                //日环比，今天减去昨天/昨天
                double proportion = gapCountOrder / countYesterday.doubleValue()*100;
                countOrder.put("proportion",decimalFormat.format(proportion)+"%");
            }
        }
        resultMap.put("countOrder", countOrder);

        //本月营业额以及本月订单量
        LocalDate firstDayOfMonth = LocalDate.now().withDayOfMonth(1);
        LocalDateTime firstDayOfMonthDateTime = LocalDateTime.of(firstDayOfMonth, LocalTime.MIN);
        LocalDate lastDayOfMonth = LocalDate.now().withDayOfMonth(firstDayOfMonth.lengthOfMonth());
        LocalDateTime lastDayOfMonthDateTime = LocalDateTime.of(lastDayOfMonth, LocalTime.MAX);
        LocalDateTime[] monthTime = new LocalDateTime[2];
        monthTime[0] = firstDayOfMonthDateTime.withHour(0).withMinute(0).withNano(0);
        monthTime[1] = lastDayOfMonthDateTime.withHour(23).withMinute(59).withNano(59);
        payRecordDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
        payRecordDOLambdaQueryWrapperX
                .eqIfPresent(PayRecordDO::getCreator, pageVO.getCreator())
                .betweenIfPresent(PayRecordDO::getPayTime, monthTime);
        Double monthAmount = payRecordMapper.todaySumAmount(payRecordDOLambdaQueryWrapperX);
        Integer countMonth = payRecordMapper.countTodayOrder(payRecordDOLambdaQueryWrapperX);

        //本月营业额
        if (monthAmount == null) {
            monthAmount=(0.00);
        }
        //本月付款订单
        if (countMonth == null) {
            countMonth= 0 ;
        }

        // 获取当前日期时间
        LocalDateTime now = LocalDateTime.now();

        // 获取上个月的YearMonth对象
        LocalDate firstDayOfLastMonth = now.withDayOfMonth(1).toLocalDate().minusMonths(1);
        LocalDateTime yesterMonthFirst = LocalDateTime.of(firstDayOfLastMonth, LocalTime.MIN);
        LocalDate lastDayOfLastMonth = now.with(TemporalAdjusters.firstDayOfMonth()).toLocalDate().minusDays(1);
        LocalDateTime yesterMonthLast = LocalDateTime.of(lastDayOfLastMonth, LocalTime.MAX);

        //营业额
        LocalDateTime[] yesterMonthDateTime = new LocalDateTime[2];
        yesterMonthDateTime[0] = yesterMonthFirst.withHour(0).withMinute(0).withNano(0);
        yesterMonthDateTime[1] = yesterMonthLast.withHour(23).withMinute(59).withNano(59);

        payRecordDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
        payRecordDOLambdaQueryWrapperX
                .eqIfPresent(PayRecordDO::getCreator, pageVO.getCreator())
                .betweenIfPresent(PayRecordDO::getPayTime, yesterMonthDateTime);
        Double yesterMonthRetailAmount = payRecordMapper.todaySumAmount(payRecordDOLambdaQueryWrapperX);
        Integer countYesterMonth = payRecordMapper.countTodayOrder(payRecordDOLambdaQueryWrapperX);
        //当日营业额
        if (yesterMonthRetailAmount == null) {
            yesterMonthRetailAmount=(0.00);
        }
        //昨日付款订单
        if (countYesterMonth == null) {
            countYesterMonth= 0 ;
        }
        //今日营业额,、昨日营业额，日环比
        Map<String,Object> retailMonthAmount = new HashMap<>();
        retailMonthAmount.put("monthAmount", monthAmount);
        retailMonthAmount.put("lastMonthAmount", yesterMonthRetailAmount);
        double gapMonthRetailAmount = monthAmount.doubleValue() - yesterMonthRetailAmount.doubleValue();
        retailMonthAmount.put("proportion","0%");
        if(gapMonthRetailAmount!=0){
            retailMonthAmount.put("proportion",gapMonthRetailAmount*100+"%");
            if(yesterMonthRetailAmount!=0){
                //日环比，今天减去昨天/昨天
                double proportion = gapMonthRetailAmount / yesterMonthRetailAmount.doubleValue()*100;
                retailMonthAmount.put("proportion",decimalFormat.format(proportion)+"%");
            }
        }
        resultMap.put("retailMonthAmount", retailMonthAmount);

        //今日订单,、昨日订单，日环比
        Map<String,Object> countMonthOrder = new HashMap<>();
        countMonthOrder.put("monthCount", countMonth);
        countMonthOrder.put("lastMonthCount", countYesterMonth);
        double gapMonthCountOrder = countMonth.doubleValue() - countYesterMonth.doubleValue();
        countMonthOrder.put("proportion","0%");
        if(gapMonthCountOrder!=0){
            countMonthOrder.put("proportion",gapMonthCountOrder*100+"%");
            if(countYesterMonth!=0){
                //日环比，今天减去昨天/昨天
                double proportion = gapMonthCountOrder / countYesterMonth.doubleValue()*100;
                countMonthOrder.put("proportion",decimalFormat.format(proportion)+"%");
            }
        }


        //年预购收益
        LocalDateTime firstDayOfYear = now.with(TemporalAdjusters.firstDayOfYear());
        LocalDateTime lastDayOfYear = now.with(TemporalAdjusters.lastDayOfYear());

        LocalDateTime[] yearDateTime = new LocalDateTime[2];
        yesterMonthDateTime[0] = firstDayOfYear.withHour(0).withMinute(0).withNano(0);
        yesterMonthDateTime[1] = lastDayOfYear.withHour(23).withMinute(59).withNano(59);

        payRecordDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
        payRecordDOLambdaQueryWrapperX
                .eqIfPresent(PayRecordDO::getCreator, pageVO.getCreator())
                .betweenIfPresent(PayRecordDO::getPayTime, yesterMonthDateTime);
        Double yearRetailAmount = payRecordMapper.todaySumAmount(payRecordDOLambdaQueryWrapperX);
        if(yearRetailAmount==null){
            yearRetailAmount = 0.00;
        }



        resultMap.put("countMonthOrder", countMonthOrder);
        resultMap.put("yearRetailAmount", yearRetailAmount);//年预估收益
        if(user!=null){
            resultMap.put("totalAmount", user.getTotalAmount());//账户余额
            resultMap.put("allAmount", user.getTotalAmount().add(user.getCastOutAmount()));//累计收益
        }

        return resultMap;
    }

}
